﻿using Light.Framework.Model;
using Light.Framework.Contract;
using Light.Utility.Security;
using Light.Framework.Castle;
using NHibernate.Criterion;
using System.Collections.Generic;
using System.Web;
using Light.Utility;
using System;

namespace Light.Framework.Component
{
    public class UserComponent : BaseComponent<User>, IUserComponent
    {

        public override OperateResult Create(User obj)
        {
            OperateResult result = new OperateResult();
            ICriterion criterion = Expression.And(Expression.Eq("Name", obj.Name), base.GetNotDeletedCriterion());

            int countExistsName = EntityMediator<User>.Count(criterion);

            if (countExistsName > 0)
            {
                result.IsSucced = false;
                result.Message = "此登录名已被使用，请重新输入！";
            }
            else
            {
                result = base.Create(obj);
            }

            return result;
        }

        public override OperateResult Update(User obj)
        {
            OperateResult result = new OperateResult();
            if (!ServerApplication.User.IsSuper && obj.IsSystem)
            {
                result.IsSucced = false;
                result.Message = "系统用户，不允许修改！";
                return result;
            }
            //else if (!obj.IsSuper && obj.ID == ServerApplication.User.ID && obj.Roles != ServerApplication.User.Roles)
            //{
            //    result.IsSucced = false;
            //    result.Message = "安全性措施，用户无法修改自己的信息！";
            //    return result;
            //}
            ICriterion crition = Expression.And(Expression.Eq("Name", obj.Name), Expression.Not(Expression.Eq("ID", obj.ID)));
            crition = Expression.And(crition, base.GetNotDeletedCriterion());

            int countExists = EntityMediator<User>.Count(crition);
            if (countExists > 0)
            {
                result.IsSucced = false;
                result.Message = "此登录名已被使用，请重新输入！";
            }
            else
            {
                result = base.Update(obj);
                if (result.IsSucced && obj.ID == ServerApplication.User.ID)
                {
                    ServerApplication.User = obj;
                }
            }

            return result;
        }

        public override OperateResult Delete(User obj)
        {
            OperateResult result = new OperateResult();
            if (obj != null && obj.ID == ServerApplication.User.ID)
            {
                result.IsSucced = false;
                result.Message = "安全性措施,禁止当前操作！";
            }
            else if (obj.IsSystem)
            {
                result.IsSucced = false;
                result.Message = "系统用户，不允许删除！";
            }
            else
            {
                result = base.Delete(obj);
            }

            return result;
        }

        protected override void BeforeSave(User obj)
        {
            if (String.IsNullOrEmpty(obj.OrganizationIDsString))
            {
                obj.OrganizationIDsString = obj.Organization.ID.ToString();
            }
            else if (!obj.OrganizationIDs.Contains(obj.Organization.ID))
            {
                obj.OrganizationIDsString = obj.Organization.ID.ToString() + "," + obj.OrganizationIDsString;
            }
        }

        protected override IList<User> Search(ICriterion criterion, int pageIndex, int pageSize, out int totalResult)
        {
            if (!ServerApplication.User.IsSuper)
            {
                criterion = Expression.And(criterion, Expression.Eq("IsSuper", false));
                //criterion = Expression.And(criterion, Expression.Eq("Organization", ServerApplication.User.Organization));
            }
            return base.Search(criterion, pageIndex, pageSize, out totalResult);
        }

        public User GetUserByName(string name)
        {

            ICriterion criterion = Expression.And(Expression.Eq("Name", name), base.GetNotDeletedCriterion());
            User user = EntityMediator<User>.FindFirst(criterion);
            ServerApplication.Evit(user);
            return user;
        }
        public User GetUserByPhone(string phone)
        {
            ICriterion criterion = Expression.And(Expression.Eq("Phone", phone), base.GetNotDeletedCriterion());
            User user = EntityMediator<User>.FindFirst(criterion);
            ServerApplication.Evit(user);
            return user;
        }

        public User GetUserByOpenID(User.OpenType type, string openId)
        {
            if (String.IsNullOrEmpty(openId))
                return null;

            ICriterion criterion = base.GetNotDeletedCriterion();
            if (type == User.OpenType.QQ)
            {
                criterion = Expression.And(Expression.Eq("OpenID_QQ", openId), criterion);
            }
            else if (type == User.OpenType.Weixin)
            {
                criterion = Expression.And(Expression.Eq("OpenID_Weixin", openId), criterion);
            }
            else if (type == User.OpenType.Weibo)
            {
                criterion = Expression.And(Expression.Eq("OpenID_Weibo", openId), criterion);
            }
            else
            {
                return null;
            }
            User user = EntityMediator<User>.FindFirst(criterion);
            ServerApplication.Evit(user);
            return user;
        }

        public User GetUserByUnionID(string unionId)
        {
            User user = null;
            if (!String.IsNullOrEmpty(unionId))
            {
                ICriterion criterion = Expression.And(Expression.Eq("UnionID", unionId), base.GetNotDeletedCriterion());
                user = EntityMediator<User>.FindFirst(criterion);
                ServerApplication.Evit(user);
            }
            return user;
        }

        public User GetUserByToken(string accessToken)
        {
            User user = null;
            if (!String.IsNullOrEmpty(accessToken))
            {
                ICriterion criterion = Expression.And(Expression.Eq("AccessToken", accessToken), base.GetNotDeletedCriterion());
                user = EntityMediator<User>.FindFirst(criterion);

                //if (user == null
                //    || user.TimeLastLogin == null
                //    || user.TimeLastLogin.Value.AddHours(1) <= DateTime.Now)
                //{
                //    user = null;
                //}
                ServerApplication.Evit(user);
            }

            return user;
        }

        public User GetUserByToken()
        {
            string token = WebHelper.GetAccessToken();

            return GetUserByToken(token);
        }


        public OperateResult Login(string username, string password)
        {
            OperateResult result = new OperateResult();

            User user = GetUserByName(username);

            if (user == null)
            {
                user = GetUserByPhone(username);
            }
            if (user != null && Base64StringCryptor.Decrypt(user.Password) == password)
            {
                if (!user.IsSuper && !user.Organization.IsFree && !ServerApplication.IsPermanent
                    && user.Organization.TimeExpire < DateTime.Now)
                {
                    result.IsSucced = false;
                    result.Message = "使用期限已到，请联系客服";
                }
                else if (user.IsLocked)
                {
                    result.IsSucced = false;
                    result.Message = "帐号异常已被锁定，请联系客服解锁";
                }
                else
                {
                    result.IsSucced = true;
                    user.IsGuest = false;

                    user.SetLoginInfos();
                    user.Update();

                    ServerApplication.User = user;

                    string message = "用户【 " + user.Name + "】登录成功";
                    ServerApplication.Logger.LogLogin(message);
                    WebHelper.SetAccessToken(user.ID);
                }
            }
            else
            {
                Model.User u = ServerApplication.User as Model.User;

                if (u != null)
                {
                    u.AccessToken = null;
                    u.Update();
                }

                ServerApplication.User = null;

                result.IsSucced = false;
                result.Message = "输入的登录名或密码有误！";
            }

            return result;
        }

        public void Logout()
        {
            if (ServerApplication.User != null)
            {
                string message = "用户【" + ServerApplication.User.Name + "】已安全退出";
                Model.User user = ServerApplication.User as Model.User;
                if (user != null)
                {
                    user.Refresh();
                    user.SetLogoutInfos();
                    user.Update();
                }

                ServerApplication.Logger.LogLogin(message);
                ServerApplication.User = null;
            }
        }

        public OperateResult ChangePassword(string username, string oldpassword, string newpassword)
        {
            OperateResult result = new OperateResult();

            User user = GetUserByName(username);
            if (user == null)
            {
                result.IsSucced = false;
                result.Message = "此用户名不存在！";
            }
            else if (Base64StringCryptor.Decrypt(user.Password) != oldpassword)
            {
                result.IsSucced = false;
                result.Message = "原密码输入错误！";
            }
            else
            {
                try
                {
                    user.Password = Base64StringCryptor.Encrypt(newpassword);
                    user.UpdateAndFlush();

                    result.IsSucced = true;
                    result.Message = "密码修改成功！";
                    ServerApplication.Logger.LogOperation("用户【" + user.Name + "】" + result.Message);
                }
                catch (CustomException ex)
                {
                    result.IsSucced = false;
                    result.Message = "密码修改失败：" + ex.Message;
                    ServerApplication.Logger.LogError("用户【" + user.Name + "】" + result.Message);
                }

            }

            return result;
        }

        public OperateResult ResetPassword(string username, string newpassword)
        {
            OperateResult result = new OperateResult();

            User user = GetUserByName(username);
            if (user == null)
            {
                result.IsSucced = false;
                result.Message = "此用户名不存在！";
            }
            else
            {
                try
                {
                    user.Password = Base64StringCryptor.Encrypt(newpassword);
                    user.UpdateAndFlush();

                    result.IsSucced = true;
                    result.Message = "密码重置成功！";
                    ServerApplication.Logger.LogOperation("用户【" + user.Name + "】" + result.Message);
                }
                catch (CustomException ex)
                {
                    result.IsSucced = false;
                    result.Message = "密码重置失败：" + ex.Message;
                    ServerApplication.Logger.LogError("用户【" + user.Name + "】" + result.Message);
                }

            }
            return result;
        }

        public OperateResult ResetPassword(int id, string newpassword)
        {
            OperateResult result = new OperateResult();

            User user = Get(id);
            if (user == null)
            {
                result.IsSucced = false;
                result.Message = "此用户不存在！";
            }
            else
            {
                try
                {
                    user.Password = Base64StringCryptor.Encrypt(newpassword);
                    user.UpdateAndFlush();

                    result.IsSucced = true;
                    result.Message = "密码重置成功！";
                    ServerApplication.Logger.LogOperation("用户【" + user.Name + "】" + result.Message);
                }
                catch (CustomException ex)
                {
                    result.IsSucced = false;
                    result.Message = "密码重置失败：" + ex.Message;
                    ServerApplication.Logger.LogError("用户【" + user.Name + "】" + result.Message);
                }

            }
            return result;
        }

        public User Get(Organization org)
        {
            ICriterion criterion = GetOrganCriertion(org);
            criterion = Expression.And(criterion, GetNotDeletedCriterion());
            return EntityMediator<User>.FindFirst(criterion);
        }
    }
}
